package com.contest.service;

import com.contest.dto.request.LoginRequest;
import com.contest.dto.request.RegisterRequest;
import com.contest.dto.response.AuthResponse;
import com.contest.dto.response.UserDto;
import com.contest.entity.User;
import com.contest.entity.UserRole;
import com.contest.exception.AuthenticationException;
import com.contest.exception.UserAlreadyExistsException;
import com.contest.repository.UserRepository;
import com.contest.security.JwtUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
public class AuthService {
    
    private static final Logger logger = LoggerFactory.getLogger(AuthService.class);
    
    @Autowired
    private AuthenticationManager authenticationManager;
    
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private PasswordEncoder passwordEncoder;
    
    @Autowired
    private JwtUtil jwtUtil;
    
    public AuthResponse login(LoginRequest loginRequest) {
        // 支持用户名或邮箱登录
        User user = userRepository.findByUsername(loginRequest.getUsernameOrEmail())
                .orElse(userRepository.findByEmail(loginRequest.getUsernameOrEmail())
                        .orElseThrow(() -> new AuthenticationException("用户不存在")));
        
        if (!user.isEnabled()) {
            throw new AuthenticationException("账户已被禁用");
        }
        
        try {
            Authentication authentication = authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(
                            user.getUsername(),
                            loginRequest.getPassword()
                    )
            );
            
            SecurityContextHolder.getContext().setAuthentication(authentication);
            String jwt = jwtUtil.generateJwtToken(authentication);
            
            UserDto userDto = convertToDto(user);
            
            logger.info("用户登录成功: {}", user.getUsername());
            return new AuthResponse(jwt, userDto);
            
        } catch (Exception e) {
            logger.error("登录失败: {}", e.getMessage());
            throw new AuthenticationException("用户名/邮箱或密码错误");
        }
    }
    
    public AuthResponse register(RegisterRequest registerRequest) {
        // 检查用户名是否已存在
        if (userRepository.existsByUsername(registerRequest.getUsername())) {
            throw new UserAlreadyExistsException("用户名已存在");
        }
        
        // 检查邮箱是否已存在
        if (userRepository.existsByEmail(registerRequest.getEmail())) {
            throw new UserAlreadyExistsException("邮箱已存在");
        }
        
        // 创建新用户
        User user = new User();
        user.setUsername(registerRequest.getUsername());
        user.setEmail(registerRequest.getEmail());
        user.setPassword(passwordEncoder.encode(registerRequest.getPassword()));
        user.setRole(registerRequest.getRole() != null ? registerRequest.getRole() : UserRole.STUDENT);
        user.setEnabled(true);
        
        User savedUser = userRepository.save(user);
        
        // 生成JWT token
        String jwt = jwtUtil.generateJwtToken(savedUser);
        UserDto userDto = convertToDto(savedUser);
        
        logger.info("用户注册成功: {}", savedUser.getUsername());
        return new AuthResponse(jwt, userDto);
    }
    
    public UserDto getCurrentUser() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication == null || !authentication.isAuthenticated()) {
            throw new AuthenticationException("用户未登录");
        }
        
        User user = (User) authentication.getPrincipal();
        return convertToDto(user);
    }
    
    public void logout() {
        SecurityContextHolder.clearContext();
        logger.info("用户登出成功");
    }
    
    private UserDto convertToDto(User user) {
        UserDto dto = new UserDto();
        dto.setId(user.getId());
        dto.setUsername(user.getUsername());
        dto.setEmail(user.getEmail());
        dto.setRole(user.getRole());
        dto.setEnabled(user.isEnabled());
        dto.setCreatedAt(user.getCreatedAt());
        dto.setUpdatedAt(user.getUpdatedAt());
        return dto;
    }
}